import { useEffect } from "react";
import { createProgram, createShader } from "../../utils";

const HelloWorld = () => {
  const randomInt = (range: number) => {
    return Math.floor(Math.random() * range);
  };

  const setRectangle = (
    gl: WebGLRenderingContext,
    x: number,
    y: number,
    width: number,
    height: number
  ) => {
    let x1 = x;
    let x2 = x + width;
    let y1 = y;
    let y2 = y + height;

    gl.bufferData(
      gl.ARRAY_BUFFER,
      new Float32Array([x1, y1, x2, y1, x1, y2, x1, y2, x2, y1, x2, y2]),
      gl.STATIC_DRAW
    );
  };

  const drawHelloWorld = () => {
    const VERTEX_SHADER_SOURCE = `
    attribute vec4 a_position;

    void main() {
      gl_Position = a_position;
    }
  `;

    const VERTEX_SHADER_SOURCE2 = `
    attribute vec2 a_position;
    uniform vec2 u_resolution;

    void main() {
      // convert the position from pixels to 0.0 to 1.0  
      vec2 zeroToOne = a_position / u_resolution;

      // convert from 0->1 to 0->2
      vec2 zeroToTwo = zeroToOne * 2.0;

      // convert from 0 -> 2 to -1 -> 1 (clip space)
      vec2 clipSpace = zeroToTwo - 1.0;

      gl_Position = vec4((clipSpace * vec2(1, -1)), 0, 1);
    }
  `;

    const FRAGMENT_SHADER_SOURCE = `
    precision mediump float;

    uniform vec4 u_color;

    void main() {
        // gl_FragColor = vec4(1, 0, 0.5, 1);
        gl_FragColor = u_color;   
    }
  `;

    const canvas = document.getElementById(
      "canvas-hello-world"
    ) as HTMLCanvasElement;
    const gl = canvas.getContext("webgl") as WebGLRenderingContext;

    const vertexShader = createShader(
      gl,
      gl.VERTEX_SHADER,
      VERTEX_SHADER_SOURCE2
    );

    const fragmentShader = createShader(
      gl,
      gl.FRAGMENT_SHADER,
      FRAGMENT_SHADER_SOURCE
    );

    if (vertexShader && fragmentShader) {
      const program = createProgram(gl, vertexShader, fragmentShader);

      if (program) {
        const positionAttributeLocation = gl.getAttribLocation(
          program,
          "a_position"
        );

        const resolutionUniformLocation = gl.getUniformLocation(
          program,
          "u_resolution"
        );

        const colorUniformLocation = gl.getUniformLocation(program, "u_color");

        const positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

        // 三个 2d 点
        // let positions = [0, 0, 0, 0.5, 0.7, 0];
        let positions = [10, 20, 80, 20, 10, 30, 10, 30, 80, 20, 80, 30];
        gl.bufferData(
          gl.ARRAY_BUFFER,
          new Float32Array(positions),
          gl.STATIC_DRAW
        );

        // rendering
        gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

        // clear canvas
        gl.clearColor(0, 0, 0, 0);
        gl.clear(gl.COLOR_BUFFER_BIT);

        gl.useProgram(program);

        gl.enableVertexAttribArray(positionAttributeLocation);

        gl.uniform2f(
          resolutionUniformLocation,
          gl.canvas.width,
          gl.canvas.height
        );

        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

        let size = 2;
        let type = gl.FLOAT;
        let nomalize = false;
        let stride = 0;
        let offset = 0;
        gl.vertexAttribPointer(
          positionAttributeLocation,
          size,
          type,
          nomalize,
          stride,
          offset
        );

        // gl.drawArrays(gl.TRIANGLES, 0, 3);
        // gl.drawArrays(gl.TRIANGLES, 0, 6);

        // draw 50 random rectangles in random colors
        for (let i = 0; i < 50; i++) {
          setRectangle(
            gl,
            randomInt(100),
            randomInt(100),
            randomInt(100),
            randomInt(100)
          );

          gl.uniform4f(
            colorUniformLocation,
            Math.random(),
            Math.random(),
            Math.random(),
            1
          );

          gl.drawArrays(gl.TRIANGLES, 0, 6);
        }
      }
    }
  };

  useEffect(() => {
    drawHelloWorld();
  }, []);

  return <canvas id="canvas-hello-world" />;
};

export default HelloWorld;
